package com.ly.cloud.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.base.Strings;
import com.ly.cloud.dto.ApplyCourseDto;
import com.ly.cloud.dto.ApplyCourseXsDto;
import com.ly.cloud.dto.CourseBaseXsDto;
import com.ly.cloud.entity.ApplyCoursePo;
import com.ly.cloud.entity.ApplyCourseXsPo;
import com.ly.cloud.entity.CourseBasePo;
import com.ly.cloud.entity.CourseBaseXmPo;
import com.ly.cloud.entity.CourseBaseXsPo;
import com.ly.cloud.exception.CloudException;
import com.ly.cloud.exception.biz.BusinessException;
import com.ly.cloud.exception.mapper.DBException;
import com.ly.cloud.mapper.ApplyCourseMapper;
import com.ly.cloud.mapper.ApplyCourseXsMapper;
import com.ly.cloud.mapper.ApprovalDetailMapper;
import com.ly.cloud.remote.feign.ApprovalServiceFeign;
import com.ly.cloud.service.ApplyCourseService;
import com.ly.cloud.service.CourseManageService;
import com.ly.cloud.utils.BeanCopyUtils;
import com.ly.cloud.vo.ApplyCourseTableVo;
import com.ly.cloud.vo.ApplyCourseVo;
import com.ly.cloud.vo.ApplyCourseXsInfoVo;
import com.ly.cloud.vo.ApplyCourseXsVo;
import com.ly.cloud.vo.CourseBaseVo;
import com.ly.cloud.vo.CourseBaseXmVo;
import com.ly.cloud.vo.CourseBaseXsVo;
import com.ly.cloud.web.utils.WebResponse;

/**
 * 课程申请Service实现类
 * 
 * @author siqi @date2018-12-17
 */
@Service
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public class ApplyCourseServiceImpl implements ApplyCourseService {

	@Autowired
	public ApplyCourseMapper applyCourseMapper;

	@Autowired
	public ApplyCourseXsMapper applyCourseXsMapper;
	
	@Autowired
	private ApprovalDetailMapper approvalDetailMapper;
	
	
	
	/**
	 * 分页查询课程申请列表
	 */
	@Override
	public Page<ApplyCourseTableVo> queryPage(Page<ApplyCourseTableVo> page, ApplyCourseDto dto) {
		try {
			return page.setRecords(applyCourseMapper.queryPage(page, dto));
		} catch (Exception e) {
			e.printStackTrace();
			throw new DBException("查询失败", e);
		}
	}

	/**
	 * 新增/修改课程申请记录
	 * @author caihuihai
	 * 2018-12-21
	 */
	@Override
	@Transactional
	public boolean insertCourse(String loginUserId,String loginUserName, ApplyCourseDto dto) {
		try {
			String kcbh = "";  //课程编号
			if(Strings.isNullOrEmpty(dto.getType())) {
				throw new BusinessException();
			}
			ApplyCoursePo po = new ApplyCoursePo();
			BeanUtils.copyProperties(dto, po);
			if(dto.getType().equals("add")) {  //新增
				//下面主要是为了方便，暂时固定规则生成课程编号
				kcbh = genKcbh(po);  //生成课程编号
				po.setKch(kcbh);
				po.setCjr(loginUserName);
				po.setCjsj(new Date());
				po.setSfyx("1");  //是否有效，新增时默认有效
				po.setSqr(loginUserId);
				po.setSqrxm(loginUserName);
				po.setSqsj(new Date());
				applyCourseMapper.insert(po);
			} else {  //修改
				kcbh = po.getKch();
				po.setXgr(loginUserName);
				po.setXgsj(new Date());
				EntityWrapper<ApplyCoursePo> ew = new EntityWrapper<>();
				ew.where("kch={0}", po.getKch());
				applyCourseMapper.update(po, ew);
			}
			//保存课程库的学时信息，先删除旧数据再保存
			saveKcxs(po.getKch(),dto.getXsDtoList());
			//如果是提交审批操作，则需要初始化审批流程,spzt:0保存，1提交审批
			if(!Strings.isNullOrEmpty(dto.getSpzt()) && "1".equals(dto.getSpzt())) {
				initApproval(kcbh);
			}
			return true;
		} catch (BusinessException e) {
			throw new BusinessException("请传type操作类型值", e);
		} catch (Exception e) {
			throw new DBException("操作异常，请重试!", e);
		}
	}

	/**
	 * 初始化审批流程
	 * @param kcbh
	 */
	private String initApproval(String kcbh) {
		try {
			Map<String, String> param = new HashMap<String, String>();
			param.put("kcbh", kcbh);
			param.put("tableName", "LY_CKBZ_GXJW_KCSJSQL");
			approvalDetailMapper.initApproval(param);
			String msg = param.get("result");// 返回最终审核状态
			return msg;
		} catch (Exception e) {
			throw new DBException("初始化审批流程出错，请联系管理员", e);
		}
		
	}

	/**
	 * 新增时先生成课程编号，这里的编码规则跟课程库的生成规则需要不一样
	 * 暂定生成规则，后续动态接编码规则
	 * 课程库的生成规则：   开课单位后两位 + 课程属性后一位 + 课程性质后一位 + 课程类别后一位 + 流水号三位
	 * 课程申请的生成规则：开课单位后两位 + 课程属性后一位 + 流水号三位
	 * @param po
	 * @return
	 */
	private String genKcbh(ApplyCoursePo po) {
		try {
			String kcbh = ""; //课程编号
			String lsh = "001";  //流水号
			//先查询是否存在课程编号，如果存在课程编号的话则查找后三位作为流水号，下一个课程编号+1开始
			EntityWrapper<ApplyCoursePo> ew = new EntityWrapper<>();
			ew.where("kkxy={0} and kcsx={1}", po.getKkxy(),po.getKcsx());
			ew.orderBy("kch", false);  //课程编号降序排
			List<ApplyCoursePo> list = applyCourseMapper.selectList(ew);
			if(list.size() > 0) {
				String oldKchStr = list.get(0).getKch();
				int oldKchLsh = Integer.parseInt(oldKchStr.substring(oldKchStr.length()-3, oldKchStr.length())); //旧的流水号
				String newKchLsh = String.valueOf(oldKchLsh + 1);  //新的流水号
				lsh = subCodeStr(newKchLsh,3); //流水号
			} 
			String kkxy = subCodeStr(po.getKkxy(),2); //开课单位后两位
			String kcsx = subCodeStr(po.getKcsx(),1); //课程属性后一位
			/*
			 * String kcxz = subCodeStr(po.getKcxz(),1); //课程性质后一位
			 * String kclb = subCodeStr(po.getKclb(),1); //课程类别后一位
            */			
			kcbh = kkxy + kcsx + lsh;  //开课单位后两位 + 课程属性后一位 + 流水号三位
			return kcbh;
		} catch (Exception e) {
			throw new CloudException("生成课程编码有问题，请联系管理员", e);
		}
	}
	
	/**
	 * 截取字符串后num位，不够num位则在前面补0
	 * @param code 字符串
	 * @param num 位数
	 * @return
	 */
	private String subCodeStr(String code,int num) {
		try {
			String value = "";
			if(code.length() < num) {   //字符串小于要截取的位数，则直接在前面补位
				value = code;
				for(int i=0;i<num-code.length();i++) {
					value = "0"+value;
				}
			} else {  //字符串大于要截取的位数，则先截取再补位
				value = code.substring(code.length()-num, code.length());
				if(value.length() != num) {
					for(int i=0;i<num-value.length();i++) {
						value = "0"+value;
					}
				}
			}
			return value;
		} catch (Exception e) {
			throw new CloudException("截取字符串有问题，请联系管理员", e);
		}
	}

	/**
	 * 保存课程库的学时信息，先删除旧数据再保存
	 * @param kch
	 * @param xsDtoList
	 */
	private void saveKcxs(String kch, List<ApplyCourseXsDto> xsDtoList) {
		try {
			EntityWrapper<ApplyCourseXsPo> ew = new EntityWrapper<>();
			ew.where("kcbh={0}", kch);
			applyCourseXsMapper.delete(ew);
			if(xsDtoList != null) {
				for (ApplyCourseXsDto xsDto : xsDtoList) {
					ApplyCourseXsPo po = new ApplyCourseXsPo();
					BeanUtils.copyProperties(xsDto, po);
					po.setKcbh(kch);
					applyCourseXsMapper.insert(po);
				}
			}
		} catch (Exception e) {
			throw new DBException("保存课程库的学时信息失败，请联系管理员", e);
		}
	}

	/**
	 * 根据课程编号查询课程申请信息（包括学时）
	 */
	@Override
	public ApplyCourseVo findKcxxByKch(String kch) {
		try {
			ApplyCourseVo vo = new ApplyCourseVo();
			//1、查询课程库基本信息
			ApplyCoursePo po = new ApplyCoursePo();
			po.setKch(kch);
			ApplyCoursePo selPo = applyCourseMapper.selectOne(po);
			BeanUtils.copyProperties(selPo, vo);
			//2、查看学时信息列表
			EntityWrapper<ApplyCourseXsPo> xsEw = new EntityWrapper<>();
			xsEw.where("kcbh={0}", kch);
			List<ApplyCourseXsPo> xsPoList = applyCourseXsMapper.selectList(xsEw);
			vo.setXsList(BeanCopyUtils.copyListProperties(xsPoList, ApplyCourseXsVo.class));
			return vo;
		} catch (Exception e) {
			throw new CloudException("查询课程申请信息失败", e);
		}
	}

	/**
	 * 批量删除申请课程；
	 * 审批状态：0保存，1已提交审核，8审批不通过，9审批通过，''无
	 */
	@Transactional
	@Override
	public boolean batchDelKc(List<ApplyCourseDto> list) {
		try {
			for (ApplyCourseDto dto : list) {
				//已提交审核和审批通过的不能删除
				if(dto.getSpzt() != null && ("1".equals(dto.getSpzt()) || "9".equals(dto.getSpzt()))) {  
					throw new BusinessException();
				}
				//1、删除课程申请表
				EntityWrapper<ApplyCoursePo> ew = new EntityWrapper<>();
				ew.where("kch={0}", dto.getKch());
				applyCourseMapper.delete(ew);
				//2、删除课程对应的学时表
				EntityWrapper<ApplyCourseXsPo> xsEw = new EntityWrapper<>();
				xsEw.where("kcbh={0}", dto.getKch());
				applyCourseXsMapper.delete(xsEw);
				//3、删除审批记录表
			}
			return true;
		} catch (BusinessException e) {
			throw new BusinessException("已提交审核和审批通过的不能删除", e);
		} catch (Exception e) {
			throw new DBException("查询课程申请信息失败", e);
		}
	}

}
